package com.niiwoo.civet.trade.listener;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.trade.constant.RabbitConstant;
import com.niiwoo.civet.trade.dao.entity.UserEvaluationRecord;
import com.niiwoo.civet.trade.dao.mapper.UserEvaluationRecordMapperExt;
import com.niiwoo.civet.trade.dto.InvestStopForEvaluationDTO;
import com.niiwoo.civet.trade.enums.EvaluationLevelEnum;
import com.niiwoo.civet.trade.enums.InvestFromTypeEnum;
import com.niiwoo.civet.trade.service.local.common.InvestCommonServer;
import com.niiwoo.civet.trade.service.local.invest.AutoBatchInvestService;
import com.niiwoo.civet.user.dto.request.AppButtonDTO;
import com.niiwoo.civet.user.dto.request.UserLetterRequestDTO;
import com.niiwoo.civet.user.enums.MessageTemplateKeyEnum;
import com.niiwoo.civet.user.enums.UserLetterTypeEnum;
import com.niiwoo.civet.user.service.UserLetterDubboService;
import com.rabbitmq.client.Channel;

import lombok.extern.slf4j.Slf4j;

/**
 * 当前投资金额已达该风险类型投资上限处理.
 * Created by daizhiyue on 2018/4/23.
 */
@Slf4j
@Component
public class InvestStopForEvaluationListener {

    @Autowired
    private UserEvaluationRecordMapperExt userEvaluationRecordMapperExt;

    @Reference(version = "1.0.0")
    UserLetterDubboService userLetterDubboService;

    @Autowired
    private AutoBatchInvestService autoBatchInvestService;
    @Autowired
    private InvestCommonServer investCommonServer;

    /**
     * 当前投资金额已达该风险类型投资上限处理
     */
    @RabbitListener(queues = {RabbitConstant.Queue.INVEST_STOP_BY_EVALUATION_DEAL})
    public void investStopSetingForEvaluation(InvestStopForEvaluationDTO investStopForEvaluationDTO, Message message, Channel channel) {
        log.info("当前投资金额已达该风险类型投资上限处理,消息内容={}", message);
        try {
            UserEvaluationRecord record = userEvaluationRecordMapperExt.selectByUserIdLimitOne(investStopForEvaluationDTO.getUserId());
            BigDecimal surplusCanInvestAmount = investCommonServer.getSurplusCanInvestAmount(record);
            if(surplusCanInvestAmount.compareTo(BigDecimal.ZERO) == 0) {
                if(investStopForEvaluationDTO.getInvestTypeEnum().equals(InvestFromTypeEnum.AUTOMATIC_INVEST)) {
                    //关闭自动投资(自动投资过程中没有余额才触发，批量投资不触发)
                    autoBatchInvestService.disableAutoInvest(investStopForEvaluationDTO.getUserId());
                }
                //发站内信提醒
                sendLetterFoStopInvestByEvaluation(record, investStopForEvaluationDTO.getInvestTypeEnum());
            }
        } catch (Exception e) {
            log.error("当前投资金额已达该风险类型投资上限处理,investStopForEvaluationDTO={},发生系统异常,原因如下:{}", JSON.toJSON(investStopForEvaluationDTO), e);
        } finally {
            doAckAnwser(message, channel);
        }
    }

    private void doAckAnwser(Message message, Channel channel) {
        try {
            //确认消息已经接收
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException ie) {
            log.error("basic ack occur exception, the reason is : {}", ie);
        }
    }


    /**
     * 自动/批量投资并已达到风险评测对应类型上限值的，发站内信提醒
     *
     * @param record
     */
    private void sendLetterFoStopInvestByEvaluation(UserEvaluationRecord record, InvestFromTypeEnum investTypeEnum) {
        EvaluationLevelEnum evaluationLevelEnum = EvaluationLevelEnum.enumOf(record.getLevel());
        log.info("自动/批量投资并已达到风险评测对应类型上限值的，发站内信提醒,传入的参数:userId={},评测等级={}", record.getUserId(), evaluationLevelEnum.getDesc());

        String typeName = "";
        String tipsForType = "";

        UserLetterRequestDTO letterRequestDTO = new UserLetterRequestDTO();
        letterRequestDTO.setToUserId(record.getUserId());
        letterRequestDTO.setUserLetterTypeEnum(UserLetterTypeEnum.ONLY_LETTER);

        //发站内信
        //你的风险类型为【%s】，当前投资金额已达该风险类型投资上限，%s
        MessageTemplateKeyEnum.LetterTemplateKeyEnum letterTemplateKeyEnum = null;

        if (evaluationLevelEnum.equals(EvaluationLevelEnum.CONSERVATIVE) || evaluationLevelEnum.equals(EvaluationLevelEnum.STEADY)) {
            tipsForType = "可提升风险类型后进行投资。";
            typeName = evaluationLevelEnum.getDesc();
            AppButtonDTO loanButton = new AppButtonDTO();
            loanButton.setLabel(AppButtonDTO.ButtonTypeEnum.EVALUATE_TEST.getDesc());
            loanButton.setButtonType(AppButtonDTO.ButtonTypeEnum.EVALUATE_TEST);
            List<AppButtonDTO> listForButton = new ArrayList<>();
            listForButton.add(loanButton);
            letterRequestDTO.setLetterButtonList(listForButton);
        } else if (evaluationLevelEnum.equals(EvaluationLevelEnum.POSITIVE)) {
            tipsForType = "暂不可投资。";
            typeName = "激进型";
        }
        List<Object> letterTemplateParamList = Arrays.asList(typeName, tipsForType);

        if(investTypeEnum.equals(InvestFromTypeEnum.BATCH_INVEST)) {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.EVALUATION_BATCH_INVEST_STOP;
        } else {
            letterTemplateKeyEnum = MessageTemplateKeyEnum.LetterTemplateKeyEnum.EVALUATION_AUTOMATIC_INVEST_STOP;
        }

        letterRequestDTO.setLetterTemplateParamList(letterTemplateParamList);
        letterRequestDTO.setLetterTemplateEnum(letterTemplateKeyEnum);
        userLetterDubboService.pushLetter(letterRequestDTO);
    }

}
